package com.qf;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitOperations;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Demo2Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo2Application.class, args);
    }

    @Bean
    public RabbitTemplate rabbitTemplate(RabbitTemplateConfigurer configurer, ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        configurer.configure(rabbitTemplate, connectionFactory);

        //绑定confirm确认回调(发送到交换机后，通过这个回调告知消息是否到大交换机)
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (ack){
//                    System.out.println("消息正常到达交换机");
                }else{
                    System.out.println("消息发送到交换机失败 -- 重新发送");
                    ReturnedMessage returned = correlationData.getReturned();
                    //获取发送失败消息的基本信息
                    //注意：消息在重发时，可能出现死循环问题。可以做重发计数（redis-incr），当重发次数达到一定数量时，需要将消息信息保存到数据库重试表中，使用定时任务发送
                    String exchange = returned.getExchange();
                    String routingKey = returned.getRoutingKey();
                    Message message = returned.getMessage();
                    rabbitTemplate.send(exchange,routingKey,message);
                }
            }
        });

        //当消息没有正常到达队列时，才触发的回调
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returned) {
                System.out.println("消息没有到达队列，重新发送");
                //重发消息
                String exchange = returned.getExchange();
                String routingKey = returned.getRoutingKey();
                Message message = returned.getMessage();
                rabbitTemplate.send(exchange,"abc.def.a",message);
            }
        });

        return rabbitTemplate;
    }
}
